home *** CD-ROM | disk | FTP | other *** search
/ ETO Development Tools 1 / ETO Development Tools 1.iso / Essentials / MacApp Documentation / MacApp AppleLink Messages / MacApp.Tech$ 6⁄1⁄90 / 1350-Re Object Style (Lon-May90 < prev    next >
Encoding:
Text File  |  1990-06-01  |  7.6 KB  |  215 lines  |  [TEXT/GEOL]

  1. Item    5722888                         26-May-90        15:16PDT
  2.  
  3. From:   MADA2                           MacApp Dev Assoc, Curtis Faith,IVC
  4.  
  5. To:     CFI                             France - Dev, CFI Paris 11,IDV
  6.  
  7. cc:     MACAPP.TECH$                    MacApp Technical
  8.  
  9. Sub:    Re: Object Style (Long!)
  10.  
  11. Nico,
  12.  
  13. How is life treating you after the WWDC?
  14.  
  15. I just finished compiling the links for the July Framework's issue and I ran
  16. across a link that you sent asking about Object Programming style, in your
  17. words, an "ethical question about OOP."
  18.  
  19. I just HAD to reply to this link as I feel you brought out an EXTREMELY
  20. IMPORTANT issue, one that deserves far more response than the one link you
  21. message received.
  22.  
  23. I will repeat the discussion here since it was quite some time ago that you
  24. sent the original:
  25.  
  26. ________________
  27.  4/20/9
  28. CFI France - Dev, CFI Paris 11,IDV
  29.  
  30.  
  31. Hi !
  32.  
  33.    A class TmyDocument, with methods like
  34.  
  35.     TMyDocument.GiveMeNewMind:TMindObject;
  36.  
  37.     And a class TGame :
  38.     TGame = OBJECT(TObject)
  39.                 fMindDocument : TMindDocument;
  40.                 (...)
  41.  
  42.                 TGame.DoGame;
  43.                 (...)
  44.     END;
  45.  
  46.    In the TGame.DoGame method, I need to get a new TMindObject. The question
  47. is:
  48. should I write a method TGame.GiveMeNewMind : TmindObject, which only purpose
  49. would be :
  50.  
  51. FUNCTION TGame.GiveMeNewMind : TMindObject
  52. BEGIN
  53.     GiveMeNewMind := fMindDocument.GiveMeNewMind;
  54. END;
  55.     And in the method TGame.DoGame (and others), I would only see:
  56.         myVar := GiveMeNewMind;
  57.  
  58. Or just call fMindDocument.GiveMeNewMind from TGame.DoGame ?
  59.  
  60. This example could seem a little stupid, since it's with a simple function
  61. call, but I have the same kind of calls with multiple indirections, like
  62. fGame.fMindDocument.Dothis...
  63.  
  64.         What do you usually do in this type of case?
  65.  
  66.                         Nico...
  67. ______________
  68. Bob Hablutzel replied:
  69. ______________
  70. 4/20/9
  71. HABLUTZEL Hablutzel, Bob
  72.  
  73. >> Questions about multiple indirections:
  74. >>
  75. >>        What do you usually do in this type of case?
  76.  
  77.  
  78. Personally, I tend to multiple indirect as much as possible. It makes for a (to
  79. me) more logical program design, hence a more usable program design, hence a
  80. more (if you'll excuse the expression) programmable program.
  81.  
  82. Bob
  83. _______________
  84.  
  85. Nico,
  86.  
  87. I must state at the onset that I strongly disagree with Bob.
  88.  
  89. There are 3 levels of OP style here:
  90.  
  91. 1) You bring up the first level in the statement:
  92. "This example could seem a little stupid, since it's with a simple function
  93. call, but I have the same kind of calls with multiple indirections, like
  94. fGame.fMindDocument.Dothis..."
  95.  
  96. Is it good style to use multiple indirections, in a sense accessing the fields
  97. of objects other than SELF?
  98.  
  99. 2) Is it good style to access methods of other objects directly everywhere or
  100. should one define one specific place for this to take place.  This corresponds
  101. to asking whether using:
  102.  
  103. SELF.GiveMeNewMind; is better than
  104.  
  105. SELF.fMindDocument.GiveMeNewMind; or SELF.GetMindDocument.GiveMeNewMind;
  106.  
  107. 3) Is is good style to access one's own fields directly or should this be done
  108. through "Accessor Methods".  Accessor methods are essentially functions that
  109. return the fields of SELF.  These usually take the form of Get's and Set's,
  110. thus instead of accessing fMindDocument.GiveMeNewMind one would use:
  111. GetMindDocument.GiveMeNewMind.
  112.  
  113. How do I begin?  Hmmm!
  114.  
  115. First let me preface by stating that Object Programming should be more than
  116. just programming with Objects.
  117.  
  118. I always think of good objects being like people in a corporation.  It is far
  119. better for a manager to be able to delegate tasks to his subordinates.  This
  120. delegation should be limited to telling them what one wants done.  It should
  121. not include telling them how to do what one wants done.
  122.  
  123. Thus in Object Programming, the less one object knows about the other objects
  124. it deals with the better.  This is always true,  I have sometimes fooled myself
  125. into thinking that I was dealing with a special case that was an exception, I
  126. was always sorry!
  127.  
  128. The idea is that you can make major implementation changes in one area of an
  129. application without affecting another area.
  130.  
  131. 1) In you example:
  132. fGame.fMindDocument.Dothis..."
  133.  
  134. You are in effect hard wiring several pieces of information:
  135.  
  136. a) This object has an associated object of type TGame.
  137. b) This TGame is referenced in a field of this object fGame.
  138. c) TGame has an associated object of type TMindDocument.
  139. d) This TMindDocument is referenced in a field of the TGame object
  140. fMindDocument.
  141. e) TMindDocument has a method DoThis that performs the desired action.
  142.  
  143. If any of the above ceases to be true you are going to have a problem.
  144.  
  145. I therefore state that it is always BAD to access fields of object other than
  146. SELF.  NEVER EVER do this!  You will be far happier if you don't.  Only use
  147. methods of objects other than self.  In fact with some Object Languages like
  148. C++ it is possible for the designer of an object Class to make it impossible to
  149. directly access fields.  This is a very useful feature as it forces one to use
  150. proper Object Programming technique.
  151.  
  152. It is unfortunately not always easy to implement this strategy with Object
  153. Pascal.  What happens when you want to find out how many Rows are in an
  154. associated TTextListView.  One can't simple ask the TTextListView object "How
  155. many rows do you have?", since TTextListViews do not have a GetNumberOfRows
  156. method.
  157.  
  158. A reasonable solution in this case is to subclass TTextListView to provide the
  159. necessary method GetNumberOfRows and then use the subclass's method.  This is a
  160. bit of a pain and it always annoys me a bit to have to do this, but it is
  161. worthwhile.  If you are using the method GetNumberOfRows and MacApp 2.1 changes
  162. the way rows are represented you will not have a problem.  You will only have
  163. to change the one  Method in the subclass to reflect the necessary changes in
  164. the TTextListView implementation.  If you are accessing
  165. fTextListView.fNumOfRows directly you will have to change this everywhere it
  166. occurs.
  167.  
  168. If one follows the above advice one will never have multiple indirection.
  169.  
  170. 2) I submit that SELF.GiveMeNewMind; is ALWAYS better than
  171.  
  172. SELF.fMindDocument.GiveMeNewMind, as it puts all the knowledge that:
  173.  
  174. a) There is an associated TMindDocument
  175. b) It is referenced by the SELF.fMindDocument field, and
  176. c) It has a GiveMeNewMindField.
  177.  
  178. in one location.  This is less of a hard and fast rule as issue number one but
  179. it is valid nonetheless.
  180.  
  181. 3) This is a further refinement of the principle of isolation of knowledge.  It
  182. is better to always use Accessor methods.  This is even less hard and fast but
  183. still remains true.
  184.  
  185. Here are a couple of rules of thumb that I use in Object Design:
  186.  
  187. The general concepts are:
  188.  
  189. 1) Keep knowledge of other objects to an absolute minimum.
  190. 2) Keep knowledge in isolated pockets, thus if one needs to know anything about
  191. another object, keep this knowledge in one place.
  192.  
  193. Which become rules:
  194. 1) Never access fields of other objects.
  195. 2) If one is going to do something like:
  196.     GetMindDocument.GiveMeNewMind more than once put it in a new method of SELF
  197. and only use this.
  198. 3) Always use Gets and Sets, the only reference to fMindDocument should be in
  199. the Function GetMindDocument.
  200. 4) Try very hard not to have more than one "." in a given line.  Thus even
  201.     GetGame.GetMindDocument.GiveMeNewMind would be considered a minor sin.  It
  202. would be better to define a method of TGame that directly returned a NewMind.
  203.  
  204. Some might claim that you will lose too much performance if you use these
  205. rules.  I have not found this to be the case.  It is amazing how much a Mac can
  206. do in a millisecond.
  207.  
  208. Having exhausted the energy in my fingers,
  209.  
  210. I remain,
  211.  
  212. Curtis
  213.  
  214.  
  215.